// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/zencore.h>

#include <memory>

#ifndef ZEN_TEST_WITH_RUNNER
#	define ZEN_TEST_WITH_RUNNER 0
#endif

#if ZEN_TEST_WITH_RUNNER
#	define DOCTEST_CONFIG_IMPLEMENT
#endif

#if ZEN_WITH_TESTS
#	include <doctest/doctest.h>
inline auto
Approx(auto Value)
{
	return doctest::Approx(Value);
}
#endif

/**
 * Test runner helper
 *
 * This acts as a thin layer between the test app and the test
 * framework, which is used to customize configuration logic
 * and to set up logging.
 *
 * If you don't want to implement custom setup then the
 * ZEN_RUN_TESTS macro can be used instead.
 */

#if ZEN_WITH_TESTS
namespace zen::testing {

class TestRunner
{
public:
	TestRunner();
	~TestRunner();

	int ApplyCommandLine(int argc, char const* const* argv);
	int Run();

private:
	struct Impl;

	std::unique_ptr<Impl> m_Impl;
};

#	define ZEN_RUN_TESTS(argC, argV)            \
		[&] {                                    \
			zen::testing::TestRunner Runner;     \
			Runner.ApplyCommandLine(argC, argV); \
			return Runner.Run();                 \
		}()

}  // namespace zen::testing
#endif

#if ZEN_TEST_WITH_RUNNER
#	undef DOCTEST_CONFIG_IMPLEMENT
#endif
